home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_13_03
/
grant
/
chrom.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-30
|
3KB
|
138 lines
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "chrom.h"
size_t CGAChromosome::m_Count = 0;
size_t CGAChromosome::m_Length = 0;
GABool* CGAChromosome::m_CrossoverMask = 0;
// Default constructor and destructor.
// Create the chromosome with bits turned on at the
// given probability.
CGAChromosome::CGAChromosome(
float Prob)
{
assert(m_Length);
m_Fitness = 0;
m_Data = new GABool[m_Length];
assert(m_Data);
m_Count++;
for (size_t Idx = 0; Idx < m_Length; Idx++) {
m_Data[Idx] = Flip(Prob);
}
m_Fitness = CalcFitness(this);
}
CGAChromosome::~CGAChromosome(void)
{
delete[] m_Data;
if (--m_Count == 0) {
delete[] m_CrossoverMask;
m_Length = 0;
m_CrossoverMask = 0;
}
}
// Mutate a single chromosome gene selected at
// random for a given probability.
void CGAChromosome::Mutate(
float Prob)
{
for (size_t Idx = 0; Idx < m_Length; Idx++) {
if (Flip(Prob)) {
m_Data[Idx] = !m_Data[Idx];
}
}
}
// Create two new offspring using a uniform crossover
// operator created with the given probability.
void Crossover(
CGAChromosome* Parent1,
CGAChromosome* Parent2,
CGAChromosome*& Child1,
CGAChromosome*& Child2,
float Prob)
{
CGAChromosome::InitializeCrossoverMask(0.5);
Child1 = new CGAChromosome();
Child2 = new CGAChromosome();
assert(Child1 && Child2);
for (size_t Idx = 0; Idx < CGAChromosome::m_Length;
Idx++) {
if (CGAChromosome::m_CrossoverMask[Idx]) {
Child1->m_Data[Idx] = Parent1->m_Data[Idx];
Child2->m_Data[Idx] = Parent2->m_Data[Idx];
} else {
Child1->m_Data[Idx] = Parent2->m_Data[Idx];
Child2->m_Data[Idx] = Parent1->m_Data[Idx];
}
}
Child1->Mutate(Prob);
Child2->Mutate(Prob);
Child1->m_Fitness = CalcFitness(Child1);
Child2->m_Fitness = CalcFitness(Child2);
}
// Calculate the difference between two chromosomes
float CalcSimilarityRatio(
CGAChromosome* Chrom1,
CGAChromosome* Chrom2)
{
for (size_t Idx = 0, MatchCount = 0;
Idx < CGAChromosome::m_Length; Idx++) {
if (Chrom1->m_Data[Idx] == Chrom2->m_Data[Idx]) {
MatchCount++;
}
}
return (float)MatchCount /
(float)CGAChromosome::m_Length;
}
// Set the passed chromosome to the opposite encoding
// of this chromosome.
CGAChromosome* CGAChromosome::Compliment(void) const
{
CGAChromosome* Chromosome = new CGAChromosome;
for (size_t Idx = 0; Idx < m_Length; Idx++) {
Chromosome->m_Data[Idx] = !m_Data[Idx];
}
Chromosome->m_Fitness = CalcFitness(Chromosome);
return Chromosome;
}
// Setup the crossover mask for creating the next
// offspring.
void CGAChromosome::InitializeCrossoverMask(
float Prob)
{
assert(m_Length && m_CrossoverMask);
for (size_t Idx = 0; Idx < m_Length; Idx++) {
m_CrossoverMask[Idx] = Flip(Prob);
}
}
// Setup the chromosomes' length and allocate memory
// for the crossover mask.
void CGAChromosome::InitializeChromosomeClass(
size_t Length)
{
assert(Length);
m_Length = Length;
if (m_Count != 0) {
delete [] m_CrossoverMask;
}
m_CrossoverMask = new GABool[m_Length];
assert(m_CrossoverMask);
}